package br.requisiteworks.controller;

import java.util.Arrays;
import java.util.List;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import br.requisiteworks.modelo.Email;
import br.requisiteworks.modelo.service.EmailService;
import br.requisiteworks.seguranca.modelo.UsuarioLogado;
import br.requisiteworks.util.persistencia.ErroBancoDados;
import br.requisiteworks.util.persistencia.ResultadoVazio;

/**
 * Implementacao de um controller que controla as operacoes relacionadas ao
 * modulo de {@link Email}s
 * 
 * @author Leandro Chaves
 * @version 1, 14/07/2010
 */
@Controller
@Secured( { "ROLE_GERENTE", "ROLE_ANALISTA" })
@RequestMapping("/email")
public class EmailController {

	@Autowired
	private EmailService emailService;

	private static final Email VAZIO = new Email();

	@RequestMapping(value = "/pesquisar.do", method = RequestMethod.GET)
	public List<Email> pesquisar(ModelMap model) {
		try {
			return this.emailService.listarEmails();
		} catch (ResultadoVazio e) {
			model.addAttribute("erro", e.getMessage());
			return null;
		}
	}

	@RequestMapping(value = "/pesquisar.do", method = RequestMethod.POST)
	public List<Email> pesquisar(@RequestParam("q") String query, ModelMap model) {

		if (query.matches("\\d+")) {
			try {
				return Arrays.asList(this.emailService.carregarEmail(Integer
						.parseInt(query)));
			} catch (ResultadoVazio e) {
				model.addAttribute("erro", e.getMessage());
				return null;
			} catch (NumberFormatException e) {
				// Nao deve ocorre devido a expressao regular
				return null;
			}
		} else {
			try {
				return this.emailService.procuraNome(query.trim());
			} catch (ResultadoVazio e) {
				model.addAttribute("erro", e.getMessage());
				return null;
			}
		}

	}

	@RequestMapping(value = "/util/pesquisar.do", method = RequestMethod.GET)
	public void pesquisar() {
	}

	@RequestMapping(value = "/util/pesquisar.do", method = RequestMethod.POST)
	public List<Email> pesquisarEmail(@RequestParam("q") String query,
			ModelMap model) {

		if (query.matches("\\d+")) {
			try {
				return Arrays.asList(this.emailService.carregarEmail(Integer
						.parseInt(query)));
			} catch (ResultadoVazio e) {
				model.addAttribute("erro", e.getMessage());
				return null;
			} catch (NumberFormatException e) {
				// Nao deve ocorre devido a expressao regular
				return null;
			}
		} else {
			try {
				return this.emailService.procuraNome(query.trim());
			} catch (ResultadoVazio e) {
				model.addAttribute("erro", e.getMessage());
				return null;
			}
		}

	}

	@RequestMapping(value = "/atualizar.do", method = RequestMethod.GET)
	public Email atualizar(@RequestParam("numero") Integer numero)
			throws ResultadoVazio {
		return this.emailService.carregarEmail(numero);
	}

	@RequestMapping(value = "/atualizar.do", method = RequestMethod.POST)
	public String atualizar(@Valid Email novoEmail, BindingResult result,
			ModelMap model) {

		/*
		 * if (result.hasErrors()) { return null; }
		 */

		try {
			Email email = this.emailService
					.carregarEmail(novoEmail.getNumero());

			email.setAssuntoEmail(novoEmail.getAssuntoEmail());
			email.setTextoEmail(novoEmail.getTextoEmail());
			email.setEmailDestino(novoEmail.getEmailDestino());

			this.emailService.atualizarEmail(email);
		} catch (ErroBancoDados e) {
			model.addAttribute("erro", e.getMessage());
		}

		return "redirect:pesquisar.do";
	}

	@RequestMapping(value = "/deletar.do", method = RequestMethod.GET)
	public String deletar(@RequestParam("numero") Integer numero, ModelMap model) {
		try {
			Email email = this.emailService.carregarEmail(numero);

			this.emailService.deletaEmail(email);
		} catch (ErroBancoDados e) {
			model.addAttribute("erro", e.getMessage());
		}

		return "redirect:pesquisar.do";
	}

	@RequestMapping(value = "/adicionar.do", method = RequestMethod.GET)
	public Email adicionar() {
		return VAZIO;
	}

	@RequestMapping(value = "/adicionar.do", method = RequestMethod.POST)
	public String adicionar(@Valid Email email, BindingResult result,
			ModelMap model) {
		/*
		 * if (result.hasErrors()) { return null; }
		 */

		email.setUsuarioRegistro(UsuarioLogado.getUsername());

		try {
			this.emailService.salvarEmail(email);
		} catch (ErroBancoDados e) {
			model.addAttribute("erro", e.getMessage());
			return null;
		}

		return "redirect:pesquisar.do";
	}
}
